package kino.command;

import kino.common.KinoContext;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import kino.client.KinoClient;
import kino.common.KinoApplicationContext;
import kino.common.KinoConstant;

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

/**
 * 命令解释器
 */
@Component
public class CommandInterpreter implements InitializingBean {

    /**
     * 命令表
     */
    private HashMap<String, KinoCommand> commandTable;

    @Autowired
    private KinoApplicationContext kinoApplicationContext;

    @Autowired
    private KinoContext kinoContext;


    public CommandInterpreter() {
        this.commandTable = new HashMap<>();
    }

    /**
     * 命令解释器执行命令行
     * @param kinoClient
     * @param inputLine
     */
    public void execute(KinoClient kinoClient, String inputLine) {
        String[] argv = inputLine.split(" ");
        String commandName = argv[0].toLowerCase(Locale.ROOT);
        if (argv.length > 0 && commandTable.containsKey(commandName)) {
            KinoCommand kinoCommand = commandTable.get(commandName);
            String[] newArgv = new String[argv.length - 1];
            for(int i = 0 ; i < argv.length - 1; i++) {
                newArgv[i] = argv[i + 1];
            }
            kinoCommand.execute(kinoClient, newArgv);
        } else {
            kinoClient.resultAppend(KinoConstant.NOT_FIND_COMMAND);
        }
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        Map<String, Object> beansWithAnnotation = kinoApplicationContext.getApplicationContext().getBeansWithAnnotation(KinoCommandEnable.class);
        for (String key : beansWithAnnotation.keySet()) {
            if (beansWithAnnotation.get(key) instanceof KinoCommand) {
                AbstractKinoCommand kinoCommand = (AbstractKinoCommand) beansWithAnnotation.get(key);
                commandTable.put(kinoCommand.getCommandName(), kinoCommand);
            }
        }
        kinoContext.commandLoading.countDown();
    }
}
